package com.yuntsg.nnsfcp.service.front.impl;

import com.yuntsg.nnsfcp.config.UploadConfig;
import com.yuntsg.nnsfcp.service.front.PrintScreenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.support.RequestContext;

import javax.annotation.Resource;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 截图
 *
 * @author ：ljx
 * @date ：Created in 2019/7/6
 */
@Slf4j
@Service
public class PrintScreenServiceImpl implements PrintScreenService {
    private final String SHELL_COMMAND = getPath() + "/phantomjs/phantomjs-2.1.1-linux-x86_64/bin/phantomjs " + getPath() + "/phantomjs/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js ";
    @Resource
    private UploadConfig uploadConfig;
    private String tempPath = null;


    /**
     * 页面截屏
     *
     * @param url url地址
     * @return 上传到服务器的地址 /home/.......
     */
    @Override
    public String print(String url) {
        log.info("截图地址: " + url);
        if (url.contains(".html")) {
            StringBuilder tempPathBuilder = new StringBuilder();
            StringBuilder returnPathBuilder = new StringBuilder();
            String htmlPageImg = uploadConfig.getHtmlPageImg();
            htmlPageImg = htmlPageImg.replace("&", getDateName());
            tempPath = tempPathBuilder
                    .append(getPath())
                    .append(htmlPageImg)
                    .append(getDateName()).append("/")
                    .append(getFileName()).append(".jpg").toString();

            String returnPath = returnPathBuilder.append(htmlPageImg).append(getDateName()).append("/").append(getFileName())
                    .append(".jpg").toString();

            String img = getImg(url);
            if ("imgOk".equals(img)) {
                return returnPath;
            }



            /*BufferedOutputStream out = null;
            try {
                byte[] byteImg = getByteImg(url);
                out = new BufferedOutputStream(new FileOutputStream(new File(tempPath)));
                out.write(byteImg);
                out.close();
                changeChmod(tempPath);
                return returnPath;
            } catch (IOException e) {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
                e.printStackTrace();
                log.error(e.toString());
            }*/
        }
        return "";
    }

    /**
     * 将目标网页转为图片字节流
     *
     * @param url 目标网页地址
     * @return 字节流
     */
    private byte[] getByteImg(String url) throws IOException {
        log.info("进入了截图方法");
        BufferedInputStream in = null;
        ByteArrayOutputStream out = null;
        File file = null;
        byte[] ret = null;
        try {
            if (exeCmd(SHELL_COMMAND + url + " " + tempPath)) {
                file = new File(tempPath);
                if (file.exists()) {
                    out = new ByteArrayOutputStream();
                    byte[] b = new byte[5120];
                    in = new BufferedInputStream(new FileInputStream(file));
                    int n;
                    while ((n = in.read(b, 0, 5120)) != -1) {
                        out.write(b, 0, n);
                    }
                    file.delete();
                    ret = out.toByteArray();
                } else {
                    log.error("文件不存在截图失败了");
                }
            } else {
                ret = new byte[]{};
            }
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                log.error(e.toString());
            }
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error(e.toString());
            }
            if (file != null && file.exists()) {
                boolean delete = file.delete();
                if (delete) {
                    log.info("删除临时文件");
                } else {
                    log.error("临时文件删除失败");
                }
            }
        }
        return ret;
    }

    /**
     * 执行CMD命令
     */
    private boolean exeCmd(String commandStr) {
        BufferedReader br = null;
        try {
            Process p = Runtime.getRuntime().exec(commandStr);
            if (p.waitFor() != 0 && p.exitValue() == 1) {
                return false;
            }
        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (Exception e) {
                    log.error(e.toString());
                }
            }
        }
        return true;
    }

    /**
     * 修改文件权限
     */
    private void changeChmod(String path) {

        //判断文件 文件夹是否存在
        File file = new File(path);
        if (!file.exists()) {
            try {
                boolean mkdirs = file.mkdirs();
                if (mkdirs) {
                    System.out.println("创建文件夹成功..");
                }
                boolean newFile = file.createNewFile();
                if (newFile) {
                    System.out.println("创建文件成功..");
                }
            } catch (IOException e) {
                log.error("截图 创建文件夹. 文件 失败了.");
                e.printStackTrace();
            }
        }

        //判断文件是否存在
        if (new File(path).exists()) {
            String[] drive = {"C:", "D:", "E:", "F:", "G:", "H:", "I:"};
            boolean contains = true;
            for (String s : drive) {
                if (path.contains(s)) {
                    contains = false;
                }
            }
            if (contains) {
                try {
                    //修改文件的权限 400 -r- --- ---
                    Runtime.getRuntime().exec("chmod 400 -R " + path);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                log.info("修改截图文件权限");
            }
        }
    }

    /**
     * 获取日期作为文件夹名
     *
     * @return
     */
    private String getDateName() {
        //获取年月日,作为"文件夹"的名字
        Calendar calendar = Calendar.getInstance();
        return "" + calendar.get(Calendar.YEAR) + (calendar.get(Calendar.MONTH) + 1) + calendar.get(Calendar.DATE);
    }

    /**
     * 生成当前时间格式的字符串,作为文件名
     *
     * @return
     */
    private String getFileName() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        return df.format(new Date());
    }

    /**
     * 得到项目的相对路径
     *
     * @return
     */
    private String getPath() {
        //服务器: tomcat/webapps/root/
        //windows: 工作路径/项目名
        try {
            String root = RequestContext.class.getResource("/").getFile();
            return new File(root).getParentFile().getParentFile().getCanonicalPath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 简化截图步骤
     *
     * @param url 截图地址
     * @return
     */
    private String getImg(String url) {
        log.info("进入了截图方法");
        BufferedInputStream in = null;
        ByteArrayOutputStream out = null;
        File file = null;
        if (exeCmd(SHELL_COMMAND + url + " " + tempPath)) {
            file = new File(tempPath);
            if (file.exists()) {
                return "imgOk";
            } else {
                log.error("文件不存在截图失败了");
            }
        }
        return null;
    }

}


